package cn.lingyangwl.agile.msg.push.core;

import cn.lingyangwl.agile.infra.module.file.model.entity.*;
import cn.lingyangwl.agile.msg.push.api.model.content.*;
import cn.lingyangwl.agile.msg.push.utils.*;
import cn.lingyangwl.framework.tool.core.*;
import lombok.Getter;
import lombok.Setter;
import org.apache.velocity.VelocityContext;

import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * 消息设置, 以下字段不一定所有的推送渠道都会用到, 请根据需求进行选择
 * @author shenguangyang
 */
public class MsgSettings {
    /**
     * key: 是调用方传递的模板数据的key
     * value.key: 是映射的模板key
     */
    @Getter
    @Setter
    protected Map<String, TplField> tplField = new HashMap<>();

    /**
     * 模板内容
     */
    @Getter
    @Setter
    protected String content;

    /**
     * 渲染结果
     */
    @Getter
    @Setter
    protected String renderContent;

    /**
     * 页面url
     */
    @Getter
    @Setter
    protected String pageUrl;

    /**
     * 媒体id
     * @see MediaMaterial#getId()
     */
    @Getter
    @Setter
    private Long mediaId;

    /**
     * 消息模板id
     */
    @Getter
    @Setter
    private String templateId;

    /**
     * 模板标题, eg: 发送邮件时候可能会使用
     */
    @Getter
    @Setter
    protected String title;


    /**
     * 完成消息字段->模板字段映射, 比如如果在页面上配置了映射 username(使用方使用的字段) => userName(消息模板中使用的字段)
     * @param msgFieldList 调用方发送的消息字段信息
     */
    public void parseField(List<MsgField> msgFieldList) {
        // 消息字段
        Map<String, MsgField> msgFieldMap = msgFieldList.stream()
            .collect(Collectors.toMap(MsgField::getKey, Function.identity(), (k1, k2) -> k2));

        this.tplField.forEach((k, v) -> {
            MsgField msgField = Optional.ofNullable(msgFieldMap.get(k)).orElse(new MsgField());
            // 优先采用渠道模板中字段指定的值, 否则采用使用方传递的值
            if (Objects.isNull(v.getValue()) || StringUtils.isEmpty(v.getValue().toString())) {
                v.setValue(Objects.isNull(msgField.getValue()) ? "" : msgField.getValue());
            }
            v.setColor(msgField.getColor());
        });
    }

    /**
     * 将模板内容渲染成目标内容, 比如将邮件模板渲染
     */
    public void evaluate() {
        if (StringUtils.isEmpty(content)) {
            return;
        }
        VelocityContext velocityContext = new VelocityContext();
        this.tplField.values().forEach(e -> velocityContext.put(e.getKey(), e.getValue()));
        this.renderContent = VelocityUtil.generate(velocityContext, content);
    }

}
